﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Particle_Editor
{
    public partial class Form1 : Form
    {
        //HELPER CLASSES
        #region HELPER CLASSES

        class Vector2D
        {
            public Vector2D(float x, float y)
            {
                this.x = x;
                this.y = y;
            }

            float x, y;

            public float X
            {
                get { return x; }
                set { x = value; }
            }

            public float Y
            {
                get { return y; }
                set { y = value; }
            }

            public static Vector2D operator *(Vector2D lhs, float rhs)
            {
                lhs.x *= rhs;
                lhs.y *= rhs;
                return lhs;
            }

            public static Vector2D operator +(Vector2D lhs, Vector2D rhs)
            {
                lhs.x += rhs.x;
                lhs.y += rhs.y;
                return lhs;
            }

            public override string ToString()
            {
                return (string)(x + ", " + y);
            }
        }

        class Flyweight
        {

        }

        class Particle
        {

            Vector2D position, initial_velocity, final_velocity, acceleration, delta_velocity, current_velocity;
            Color color;
            float lifespan, life_timer, scale_start, scale_end, delta_s, scale_current, speed, accel, opacity_start, opacity_current, delta_o, opacity_end;
            float delta_a, delta_r, delta_b, delta_g;
            int alpha, red, green, blue;
            int alpha_s, red_s, green_s, blue_s;
            int alpha_e, red_e, green_e, blue_e;
            float alpha_c, red_c, green_c, blue_c;

            public Vector2D Current_velocity
            {
                get { return current_velocity; }
                set { current_velocity = value; }
            }
            public Vector2D Delta_velocity
            {
                get { return delta_velocity; }
                set { delta_velocity = value; }
            }
            public float Blue_c
            {
                get { return blue_c; }
                set { blue_c = value; }
            }

            public float Green_c
            {
                get { return green_c; }
                set { green_c = value; }
            }

            public float Red_c
            {
                get { return red_c; }
                set { red_c = value; }
            }

            public float Alpha_c
            {
                get { return alpha_c; }
                set { alpha_c = value; }
            }

            public float Delta_a
            {
                get { return delta_a; }
                set { delta_a = value; }
            }

            public float Delta_r
            {
                get { return delta_r; }
                set { delta_r = value; }
            }

            public float Delta_b
            {
                get { return delta_b; }
                set { delta_b = value; }
            }

            public float Delta_g
            {
                get { return delta_g; }
                set { delta_g = value; }
            }

            public Particle()
            {
                alpha = red = green = blue = -1;
                delta_velocity = new Vector2D(0, 0);
                current_velocity = new Vector2D(0, 0);
            }

            public int Alpha_e
            {
                get { return alpha_e; }
                set { alpha_e = value; }
            }

            public int Red_e
            {
                get { return red_e; }
                set { red_e = value; }
            }

            public int Green_e
            {
                get { return green_e; }
                set { green_e = value; }
            }

            public int Blue_e
            {
                get { return blue_e; }
                set { blue_e = value; }
            }

            public int Alpha_s
            {
                get { return alpha_s; }
                set { alpha_s = value; }
            }

            public int Red_s
            {
                get { return red_s; }
                set { red_s = value; }
            }

            public int Green_s
            {
                get { return green_s; }
                set { green_s = value; }
            }

            public int Blue_s
            {
                get { return blue_s; }
                set { blue_s = value; }
            }


            public int Alpha
            {
                get { return alpha; }
                set { alpha = value; }
            }

            public int Red
            {
                get { return red; }
                set { red = value; }
            }

            public int Green
            {
                get { return green; }
                set { green = value; }
            }

            public int Blue
            {
                get { return blue; }
                set { blue = value; }
            }

            public float Delta_o
            {
                get { return delta_o; }
                set { delta_o = value; }
            }

            public float Delta_s
            {
                get { return delta_s; }
                set { delta_s = value; }
            }

            public float Opacity_end
            {
                get { return opacity_end; }
                set { opacity_end = value; }
            }

            public float Opacity_start
            {
                get { return opacity_start; }
                set { opacity_start = value; }
            }

            public float Scale_current
            {
                get { return scale_current; }
                set { scale_current = value; }
            }

            public float Scale_end
            {
                get { return scale_end; }
                set { scale_end = value; }
            }
            int image_id, width, height;


            public int Height
            {
                get { return height; }
                set { height = value; }
            }

            public int Width
            {
                get { return width; }
                set { width = value; }
            }

            float vdt;

            public float Vdt
            {
                get { return vdt; }
                set { vdt = value; }
            }

            public float Speed
            {
                get { return speed; }
                set { speed = value; }
            }

            public float Start_scale
            {
                get { return scale_start; }
                set { scale_start = value; }
            }

            public Vector2D Final_velocity
            {
                get { return final_velocity; }
                set { final_velocity = value; }
            }
            public float Life_timer
            {
                get { return life_timer; }
                set { life_timer = value; }
            }

            public int Image_id
            {
                get { return image_id; }
                set { image_id = value; }
            }

            public float Lifespan
            {
                get { return lifespan; }
                set { lifespan = value; }
            }

            public Vector2D Acceleration
            {
                get { return acceleration; }
                set { acceleration = value; }
            }

            public Vector2D Initial_velocity
            {
                get { return initial_velocity; }
                set { initial_velocity = value; }
            }

            public Vector2D Position
            {
                get { return position; }
                set { position = value; }
            }

            public Color Color
            {
                get { return color; }
                set { color = value; }
            }

            public void Update(float elapsed_time)
            {
                //Update scale
                scale_current += delta_s * elapsed_time;

                //if random color is not selected
                if (alpha == -1 && red == -1 && blue == -1 && green == -1)
                {
                    //Update color
                    alpha_c += (delta_a * elapsed_time);
                    red_c += (delta_r * elapsed_time);
                    green_c += (delta_g * elapsed_time);
                    blue_c += (delta_b * elapsed_time);
                }


                current_velocity.X = (current_velocity.X + delta_velocity.X) + acceleration.X * (elapsed_time / 1000);
                current_velocity.Y = (current_velocity.Y + delta_velocity.Y) + acceleration.Y * (elapsed_time / 1000);

                initial_velocity.X = initial_velocity.X + acceleration.X * (elapsed_time / 1000);
                initial_velocity.Y = initial_velocity.Y + acceleration.Y * (elapsed_time / 1000);


                //Add when necessary
                position.X = position.X + current_velocity.X * (elapsed_time / 1000);
                position.Y = position.Y + current_velocity.Y * (elapsed_time / 1000);

                //position.X = position.X + initial_velocity.X * (elapsed_time / 1000);
                //position.Y = position.Y + initial_velocity.Y * (elapsed_time / 1000);

                life_timer += elapsed_time;
            }

            public void Render()
            {
                //Adjust width and height
                float adjusted_width = (width * scale_current);
                float adjusted_height = (height * scale_current);

                //Create color
                Color c;
                if (alpha == -1 || blue == -1 || red == -1 || green == -1)
                    c = Color.FromArgb((int)alpha_c, (int)red_c, (int)green_c, (int)blue_c);
                else
                    c = Color.FromArgb(alpha, red, green, blue);

                //Draw particle
                SGP.CSGP_TextureManager.GetInstance().Draw(image_id, (int)(position.X - (adjusted_width / 2)), (int)(position.Y - (adjusted_height / 2)), scale_current, scale_current, Rectangle.Empty, 0, 0, 0, c);
            }
        }

        class Emitter
        {
            List<Particle> live_list, dead_list;
            int image_id, max_particles;
            float spawn_timer, spawn_timer_max, scale_start, scale_end;
            float offset_x_left, offset_x_right, offset_y_above, offset_y_below;

            public float Offset_x_left
            {
                get { return offset_x_left; }
                set { offset_x_left = value; }
            }

            public float Offset_x_right
            {
                get { return offset_x_right; }
                set { offset_x_right = value; }
            }

            public float Offset_y_above
            {
                get { return offset_y_above; }
                set { offset_y_above = value; }
            }

            public float Offset_y_below
            {
                get { return offset_y_below; }
                set { offset_y_below = value; }
            }
            bool randomColor;
            string name;
            //for color change from s to e
            int alpha_s, red_s, green_s, blue_s;
            int alpha_e, red_e, green_e, blue_e;

            public override string ToString()
            {
                return name;
            }

            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            public Emitter()
            {
                randomColor = false;
                initial_velocity_max = new Vector2D(0, 0);
                initial_velocity_min = new Vector2D(0, 0);
                final_velocity_max = new Vector2D(0, 0);
                final_velocity_min = new Vector2D(0, 0);
            }

            public bool RandomColor
            {
                get { return randomColor; }
                set { randomColor = value; }
            }



            public int Blue_e
            {
                get { return blue_e; }
                set { blue_e = value; }
            }

            public int Green_e
            {
                get { return green_e; }
                set { green_e = value; }
            }

            public int Red_e
            {
                get { return red_e; }
                set { red_e = value; }
            }

            public int Alpha_e
            {
                get { return alpha_e; }
                set { alpha_e = value; }
            }

            public int Alpha_s
            {
                get { return alpha_s; }
                set { alpha_s = value; }
            }

            public int Red_s
            {
                get { return red_s; }
                set { red_s = value; }
            }

            public int Green_s
            {
                get { return green_s; }
                set { green_s = value; }
            }

            public int Blue_s
            {
                get { return blue_s; }
                set { blue_s = value; }
            }

            public float Scale_start
            {
                get { return scale_start; }
                set { scale_start = value; }
            }

            public float Scale_end
            {
                get { return scale_end; }
                set { scale_end = value; }
            }
            Vector2D position;
            Random rand;
            bool burst;
            int burst_number;

            public int Burst_number
            {
                get { return burst_number; }
                set { burst_number = value; }
            }

            public bool Burst
            {
                get { return burst; }
                set { burst = value; }
            }

            int lifespan, lifespan_max;

            public int Lifespan_max
            {
                get { return lifespan_max; }
                set { lifespan_max = value; }
            }

            public int Lifespan
            {
                get { return lifespan; }
                set { lifespan = value; }
            }

            float scale;

            public float Scale
            {
                get { return scale; }
                set { scale = value; }
            }
            float speed, accel;

            public float Speed
            {
                get { return speed; }
                set { speed = value; }
            }

            public float Accel
            {
                get { return accel; }
                set { accel = value; }
            }
            Vector2D velocity, acceleration;
            Vector2D velocity_max, acceleration_max;
            Vector2D initial_velocity_min, final_velocity_min, initial_velocity_max, final_velocity_max;

            public Vector2D Final_velocity_max
            {
                get { return final_velocity_max; }
                set { final_velocity_max = value; }
            }

            public Vector2D Initial_velocity_max
            {
                get { return initial_velocity_max; }
                set { initial_velocity_max = value; }
            }

            public Vector2D Final_velocity_min
            {
                get { return final_velocity_min; }
                set { final_velocity_min = value; }
            }

            public Vector2D Initial_velocity_min
            {
                get { return initial_velocity_min; }
                set { initial_velocity_min = value; }
            }

            public Vector2D Velocity_max
            {
                get { return velocity_max; }
                set { velocity_max = value; }
            }

            public Vector2D Acceleration_max
            {
                get { return acceleration_max; }
                set { acceleration_max = value; }
            }

            public Vector2D Velocity
            {
                get { return velocity; }
                set { velocity = value; }
            }

            public Vector2D Acceleration
            {
                get { return acceleration; }
                set { acceleration = value; }
            }

            public Vector2D Position
            {
                get { return position; }
                set { position = value; }
            }
            public float Spawn_timer_max
            {
                get { return spawn_timer_max; }
                set { spawn_timer_max = value; }
            }

            public float Spawn_timer
            {
                get { return spawn_timer; }
                set { spawn_timer = value; }
            }

            public int Max_particles
            {
                get { return max_particles; }
                set { max_particles = value; }
            }

            public int Image_id
            {
                get { return image_id; }
                set { image_id = value; }
            }

            public void KillParticle(Particle particle)
            {
                live_list.Remove(particle);
                particle.Alpha = particle.Red = particle.Blue = particle.Green = -1;
                dead_list.Add(particle);
            }

            public void SpawnParticle()
            {
                if (live_list.Count != max_particles)
                {
                    if (dead_list.Count != 0)
                    {
                        //Grab a particle from the dead list
                        Particle particle = dead_list.ElementAt(0);
                        dead_list.RemoveAt(0);


                        //Determine random offset
                        float offset_x = (float)rand.Next((int)offset_x_left, (int)offset_x_right);
                        float offset_y = (float)rand.Next((int)offset_y_above, (int)offset_y_below);
                        //Set Position
                        particle.Position = new Vector2D(position.X + offset_x, position.Y + offset_y);

                        //Set Velocity
                        Vector2D random_vel = new Vector2D(rand.Next((int)velocity.X, (int)velocity_max.X), rand.Next((int)velocity.Y, (int)velocity_max.Y));
                        particle.Initial_velocity = new Vector2D(random_vel.X, random_vel.Y);

                        Vector2D random_initial = new Vector2D(rand.Next((int)initial_velocity_min.X, (int)initial_velocity_max.X), rand.Next((int)initial_velocity_max.Y, (int)initial_velocity_max.Y));
                        particle.Initial_velocity = random_initial;

                        Vector2D random_final = new Vector2D(rand.Next((int)final_velocity_min.X, (int)final_velocity_min.X), rand.Next((int)final_velocity_max.Y, (int)final_velocity_max.Y));
                        particle.Final_velocity = random_final;

                        particle.Current_velocity = random_initial;
                        particle.Delta_velocity = new Vector2D((random_final.X - random_initial.X) / lifespan_max, (random_final.Y - random_initial.Y) / lifespan_max);

                        //Set Speed
                        particle.Speed = speed;

                        //Set Acceleration
                        particle.Acceleration = new Vector2D(acceleration.X, acceleration.Y);

                        //Set Width and Height
                        particle.Width = SGP.CSGP_TextureManager.GetInstance().GetTextureWidth(image_id);
                        particle.Height = SGP.CSGP_TextureManager.GetInstance().GetTextureHeight(image_id);

                        //Set Lifespan
                        if (lifespan_max < lifespan)
                            lifespan = lifespan_max;
                        particle.Lifespan = rand.Next(lifespan, lifespan_max);
                        particle.Life_timer = 0.0f;

                        //Set Scale
                        if (scale_start == 0.0f && scale_end == 0.0f)
                        {
                            scale_start = 1;
                            scale_end = 0;
                        }
                        particle.Start_scale = scale_start;
                        particle.Scale_end = scale_end;
                        if (lifespan_max > 0)
                            particle.Delta_s = (scale_end - scale_start) / (lifespan_max);
                        particle.Scale_current = scale_start;

                        //Set colors
                        if (randomColor)
                        {
                            int a = rand.Next(0, 255);
                            int r = rand.Next(0, 255);
                            int b = rand.Next(0, 255);
                            int g = rand.Next(0, 255);

                            particle.Alpha = a;
                            particle.Blue = b;
                            particle.Red = r;
                            particle.Green = g;
                        }
                        else
                        {
                            //Set starting color
                            particle.Alpha_s = alpha_s;
                            particle.Red_s = red_s;
                            particle.Green_s = green_s;
                            particle.Blue_s = blue_s;

                            //Set ending color
                            particle.Alpha_e = alpha_e;
                            particle.Red_e = red_e;
                            particle.Blue_e = blue_e;
                            particle.Green_e = green_e;

                            //Determine deltas
                            if (lifespan_max > 0)
                            {
                                particle.Delta_a = (float)(alpha_e - alpha_s) / (lifespan_max);
                                particle.Delta_r = (float)(red_e - red_s) / (lifespan_max);
                                particle.Delta_g = (float)(green_e - green_s) / (lifespan_max);
                                particle.Delta_b = (float)(blue_e - blue_s) / (lifespan_max);
                            }

                            //Set Starting colors
                            particle.Alpha_c = alpha_s;
                            particle.Red_c = red_s;
                            particle.Green_c = green_s;
                            particle.Blue_c = blue_s;

                        }

                        //Add Particle to live list
                        live_list.Add(particle);
                    }
                }
            }

            public void Update(float elapsed_time)
            {
                //Update spawn timer
                spawn_timer += elapsed_time;

                //Check if it is time to spawn particles
                if (spawn_timer >= spawn_timer_max)
                {
                    if (burst)
                    {
                        for (int i = 0; i < burst_number; i++)
                        {
                            SpawnParticle();
                        }
                        spawn_timer = 0.0f;
                    }
                    else
                    {
                        SpawnParticle();
                        spawn_timer = 0.0f;
                    }

                }

                for (int i = live_list.Count - 1; i > -1; i--)
                {
                    Particle particle = live_list.ElementAt(i);

                    particle.Update(elapsed_time);

                    //if particle in live list is dead remove it
                    if (particle.Life_timer >= particle.Lifespan)
                        KillParticle(particle);
                }
            }

            public void Render()
            {
                foreach (Particle particle in live_list)
                    particle.Render();
            }

            public void Initialize()
            {
                max_particles = 100;
                rand = new Random();
                position = new Vector2D(0, 0);
                spawn_timer_max = 90.0f;
                scale = 1;
                speed = accel = 1;
                velocity = new Vector2D(0, 1);
                velocity_max = new Vector2D(0, 1);
                acceleration = new Vector2D(0, 1);

                live_list = new List<Particle>();
                dead_list = new List<Particle>();
                for (int i = 0; i < max_particles; i++)
                {
                    Particle particle = new Particle();
                    particle.Image_id = image_id;
                    particle.Initial_velocity = new Vector2D(0, 0);
                    particle.Final_velocity = new Vector2D(0, 0);
                    particle.Acceleration = new Vector2D(0, 0);
                    particle.Width = SGP.CSGP_TextureManager.GetInstance().GetTextureWidth(image_id);
                    particle.Height = SGP.CSGP_TextureManager.GetInstance().GetTextureHeight(image_id);
                    dead_list.Add(particle);
                }

            }
        }
        #endregion

        //FIELDS/METHODS
        #region FIELDS/METHODS
        bool looping, drawing;
        Vector2D position, gravitation_source;
        Emitter emitter;
        int selected_id;
        List<int> image_ids;
        List<Emitter> emitter_list;
        SGP.CSGP_Direct3D D3D;
        SGP.CSGP_TextureManager TM;
        Random random;

        public bool Looping
        {
            get { return looping; }
            set { looping = value; }
        }

        #endregion

        //STARTUP/SHUTDOWN
        #region STARTUP AND SHUTDOWN
        public Form1()
        {
            InitializeComponent();
        }

        public void Initialize()
        {
            looping = true;
            emitter = null;
            selected_id = -1;
            emitter_list = new List<Emitter>();
            image_ids = new List<int>();
            random = new Random();
            position = new Vector2D(0, 0);
            gravitation_source = new Vector2D(0, 0);

            //Setup DirectX and Texture manager
            D3D = SGP.CSGP_Direct3D.GetInstance();
            TM = SGP.CSGP_TextureManager.GetInstance();
            D3D.Initialize(particleRenderPanel, false);
            D3D.AddRenderTarget(imageSelectionPanel);
            TM.Initialize(D3D.Device, D3D.Sprite);
        }

        //The shutdown process
        public void Terminate()
        {
            for (int i = 0; i < image_ids.Count; i++)
            {
                TM.UnloadTexture(i);
            }
            TM.Terminate();
            D3D.Terminate();
        }

        #endregion

        //UPDATE && RENDER
        #region UPDATE && RENDER

        public void Update(float elapsed_time)
        {
            foreach (Emitter emitter in emitter_list)
                emitter.Update(elapsed_time);
        }

        public void Render()
        {
            D3D.Clear(particleRenderPanel, Color.Black);
            D3D.DeviceBegin();
            D3D.SpriteBegin();
            {
                foreach (Emitter emitter in emitter_list)
                    emitter.Render();

                D3D.DrawLine((int)(position.X - 5), (int)position.Y, (int)(position.X + 5), (int)position.Y, Color.Red, 1);
                D3D.DrawLine((int)position.X, (int)(position.Y - 5), (int)position.X, (int)(position.Y + 5), Color.Red, 1);

                D3D.DrawLine((int)(gravitation_source.X - 5), (int)gravitation_source.Y, (int)(gravitation_source.X + 5), (int)gravitation_source.Y, Color.Red, 1);
                D3D.DrawLine((int)gravitation_source.X, (int)(gravitation_source.Y - 5), (int)gravitation_source.X, (int)(gravitation_source.Y + 5), Color.Red, 1);
            }
            D3D.SpriteEnd();
            D3D.DeviceEnd();
            D3D.Present();
        }

        public void RenderImageSelectionPanel()
        {
            D3D.Clear(imageSelectionPanel, Color.Black);
            D3D.DeviceBegin();
            D3D.SpriteBegin();
            {
                int count = 0;
                foreach (int i in image_ids)
                {
                    float scale_x = 100.0f / (float)TM.GetTextureWidth(i);
                    float scale_y = (imageSelectionPanel.Size.Height) / (float)TM.GetTextureHeight(i);

                    TM.Draw(i, 100 * count, 0, scale_x, scale_y);

                    Rectangle rect = new Rectangle(100 * count, 0, 100, 90);
                    if (selected_id == i)
                        D3D.DrawHollowRect(rect, Color.Yellow, 2);
                    else
                        D3D.DrawHollowRect(rect, Color.Black, 2);

                    count++;
                }
            }
            D3D.SpriteEnd();
            D3D.DeviceEnd();
            D3D.Present();
        }

        #endregion

        //BUTTONS
        #region BUTTONS

        #endregion

        //MENUS
        #region MENUS

        #endregion

        //FORM EVENTS
        #region FORM EVENTS

        //Begins the shutdown process
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            looping = false;
        }
        #endregion

        int GetRenderPanelWidth()
        {
            return particleRenderPanel.Width;
        }

        int GetRenderPanelHeight()
        {
            return particleRenderPanel.Height;
        }

        private void particleRenderPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (emitter == null)
                return;

            if (e.Button == MouseButtons.Left)
                drawing = true;
            else if (e.Button == MouseButtons.Right)
                emitter.Position = position = new Vector2D(e.X, e.Y);

        }
        //NUMERIC UP DOWN VALUES CHANGED
        #region NUMERIC UP DOWN VALUES CHANGED


        private void accelYNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Acceleration = new Vector2D(emitter.Acceleration.X, (float)accelYNumericUpDown.Value);
        }

        private void accelXNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Acceleration = new Vector2D((float)accelXNumericUpDown.Value, emitter.Acceleration.Y);

        }

        private void endColorBNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Blue_e = Math.Abs((int)endColorBNumericUpDown.Value);
            blueEndTrackBar.Value = (int)endColorBNumericUpDown.Value;

        }

        private void endColorGNumericUpDown_ValueChanged(object sender, EventArgs e)
        {

        }

        private void endColorRNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Red_e = Math.Abs((int)endColorRNumericUpDown.Value);
            redEndTrackBar.Value = (int)endColorRNumericUpDown.Value;
        }

        private void startColorRNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            emitter.Red_s = (int)startColorRNumericUpDown.Value;
        }

        private void startColorGNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Green_s = Math.Abs((int)startColorGNumericUpDown.Value);
            greenStartTrackBar.Value = (int)startColorGNumericUpDown.Value;
        }

        private void startColorBNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Blue_s = Math.Abs((int)startColorBNumericUpDown.Value);
            blueStartTrackBar.Value = (int)startColorBNumericUpDown.Value;
        }

        private void scaleNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Scale_start = (float)scaleStartNumericUpDown.Value;
        }

        private void lifespanNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Lifespan = (int)lifespanNumericUpDown.Value;
            lifespanMaxNumericUpDown.Minimum = lifespanNumericUpDown.Value;
        }
        #endregion

        private void particleLimitNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Max_particles = (int)particleLimitNumericUpDown.Value;
        }

        private void spawnRateNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Spawn_timer_max = (float)spawnRateNumericUpDown.Value;
        }

        private void lifespanMaxNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Lifespan_max = (int)lifespanMaxNumericUpDown.Value;
            lifespanMaxNumericUpDown.Minimum = lifespanNumericUpDown.Value;
        }

        private void burstCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Burst = burstCheckBox.Checked;
        }

        private void burstAnountNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Burst_number = (int)burstAnountNumericUpDown.Value;
        }

        private void scaleEndnumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Scale_end = (float)scaleEndnumericUpDown.Value;
        }

        private void colorRandomCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.RandomColor = colorRandomCheckBox.Checked;
        }

        private void endColorANumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Alpha_e = Math.Abs((int)endColorANumericUpDown.Value);
            alphaEndTrackBar.Value = (int)endColorANumericUpDown.Value;
        }

        private void endColorGNumericUpDown_ValueChanged_1(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Green_e = Math.Abs((int)endColorGNumericUpDown.Value);
            greenEndTrackBar.Value = (int)endColorGNumericUpDown.Value;
        }

        private void startColorANumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Alpha_s = Math.Abs((int)startColorANumericUpDown.Value);
            alphaStartTrackBar.Value = (int)startColorANumericUpDown.Value;
        }

        private void startColorRNumericUpDown_ValueChanged_1(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Red_s = Math.Abs((int)startColorRNumericUpDown.Value);
            redStartTrackBar.Value = (int)startColorRNumericUpDown.Value;
        }

        private void AddEmitterbutton_Click(object sender, EventArgs e)
        {
            if (selected_id == -1)
                return;

            Emitter emit = new Emitter();

            if (emitterNameTextBox.Text == "")
                emit.Name = "untitled";
            else
                emit.Name = emitterNameTextBox.Text;


            //Load Selected Image

            //emitter.Image_id = TM.LoadTexture("../../bloodparticle_large.png");
            emit.Image_id = selected_id;
            emit.Initialize();

            emitter_list.Add(emit);
            emitterListBox.Items.Add(emit);
        }

        private void removeEmitterButton_Click(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter_list.Remove(emitter);
            emitterListBox.Items.Remove(emitter);

        }

        private void loadNewImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Image Files ( JPEG,BMP,PNG )|*.jpg;*.jpeg;*.bmp;*.png;|JPEG Files ( *.jpg;*.jpeg )|*.jpg;*.jpeg|BMP Files ( *.bmp )|*.bmp|PNG Files ( *.png )|*.png| All Files (*.*)|*.*";

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                int id = TM.LoadTexture(dlg.FileName);
                image_ids.Add(id);
            }
        }

        private void emitterListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            emitter = (Emitter)emitterListBox.SelectedItem;

            SetValues();

        }

        public void SetValues()
        {
            if (emitter == null)
                return;

            lifespanNumericUpDown.Value = emitter.Lifespan;
            lifespanMaxNumericUpDown.Value = emitter.Lifespan_max;
            burstCheckBox.Checked = emitter.Burst;
            burstAnountNumericUpDown.Value = emitter.Burst_number;
            spawnRateNumericUpDown.Value = (decimal)emitter.Spawn_timer_max;
            particleLimitNumericUpDown.Value = emitter.Max_particles;
            scaleEndnumericUpDown.Value = (decimal)emitter.Scale_end;
            scaleStartNumericUpDown.Value = (decimal)emitter.Scale_start;
            startColorANumericUpDown.Value = emitter.Alpha_s;
            startColorRNumericUpDown.Value = emitter.Red_s;
            startColorGNumericUpDown.Value = emitter.Green_s;
            startColorBNumericUpDown.Value = emitter.Blue_s;
            endColorANumericUpDown.Value = emitter.Alpha_e;
            endColorRNumericUpDown.Value = emitter.Red_e;
            endColorGNumericUpDown.Value = emitter.Green_e;
            endColorBNumericUpDown.Value = emitter.Blue_e;
            colorRandomCheckBox.Checked = emitter.RandomColor;
            accelXNumericUpDown.Value = (decimal)emitter.Acceleration.X;
            accelYNumericUpDown.Value = (decimal)emitter.Acceleration.Y;
            startingOffsetXLeftnumericUpDown.Value = (decimal)emitter.Offset_x_left;
            startingOffsetXRightnumericUpDown.Value = (decimal)emitter.Offset_x_right;
            startingOffsetYAbovenumericUpDown.Value = (decimal)emitter.Offset_y_above;
            startingOffsetYBelownumericUpDown.Value = (decimal)emitter.Offset_y_below;
            startVelocityMaxXNumericUpDown.Value = (decimal)emitter.Initial_velocity_max.X;
            startVelocityMaxYNumericUpDown.Value = (decimal)emitter.Initial_velocity_max.Y;
            startVelocityMinXNumericUpDown.Value = (decimal)emitter.Initial_velocity_min.X;
            startVelocityMinYNumericUpDown.Value = (decimal)emitter.Initial_velocity_min.Y;
            endVelocityMaxXNumericUpDown.Value = (decimal)emitter.Final_velocity_max.X;
            endVelocityMaxYNumericUpDown.Value = (decimal)emitter.Final_velocity_max.Y;
            endVelocityMinXNumericUpDown.Value = (decimal)emitter.Final_velocity_min.X;
            endVelocityMinYNumericUpDown.Value = (decimal)emitter.Final_velocity_min.Y;

        }

        private void imageSelectionPanel_MouseClick(object sender, MouseEventArgs e)
        {

            int count = 0;
            foreach (int i in image_ids)
            {
                Rectangle rect = new Rectangle(100 * count, 0, 100, imageSelectionPanel.Size.Height);

                if (e.Location.X > rect.Left && e.Location.X < rect.Right && e.Location.Y > 0 && e.Location.Y < imageSelectionPanel.Size.Height)
                {
                    selected_id = i;
                }
                count++;
            }
        }

        private void startingOffsetYBelownumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Offset_y_below = (float)startingOffsetYBelownumericUpDown.Value;

            if (startingOffsetYAbovenumericUpDown.Value > startingOffsetYBelownumericUpDown.Value)
                startingOffsetYBelownumericUpDown.Value = startingOffsetYAbovenumericUpDown.Value;
        }

        private void startingOffsetYAbovenumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Offset_y_above = (float)startingOffsetYAbovenumericUpDown.Value;

            if (startingOffsetYAbovenumericUpDown.Value > startingOffsetYBelownumericUpDown.Value)
                startingOffsetYBelownumericUpDown.Value = startingOffsetYAbovenumericUpDown.Value;
        }

        private void startingOffsetXRightnumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Offset_x_right = (float)startingOffsetXRightnumericUpDown.Value;

            if (startingOffsetXRightnumericUpDown.Value < startingOffsetXLeftnumericUpDown.Value)
                startingOffsetXRightnumericUpDown.Value = startingOffsetXLeftnumericUpDown.Value;
        }

        private void startingOffsetXLeftnumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Offset_x_left = (float)startingOffsetXLeftnumericUpDown.Value;

            if (startingOffsetXRightnumericUpDown.Value < startingOffsetXLeftnumericUpDown.Value)
                startingOffsetXRightnumericUpDown.Value = startingOffsetXLeftnumericUpDown.Value;
        }

        private void randomizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            int rand;

            //Set Lifespan Range
            if (lifespanRandomizeCheckBox.Checked)
            {
                lifespanNumericUpDown.Value = random.Next((int)lifespanNumericUpDown.Minimum, (int)lifespanNumericUpDown.Maximum);
                lifespanMaxNumericUpDown.Value = random.Next((int)lifespanNumericUpDown.Value, (int)lifespanMaxNumericUpDown.Maximum);
            }

            //Set Burst Mode
            if (burstModeRandomizeCheckBox.Checked)
            {
                rand = random.Next(1, 3);
                if (rand == 1)
                    burstCheckBox.Checked = false;
                else if (rand == 2)
                    burstCheckBox.Checked = true;

                //If burst mode is active set amount to burst
                if (burstCheckBox.Checked)
                    burstAnountNumericUpDown.Value = random.Next((int)burstAnountNumericUpDown.Minimum, (int)burstAnountNumericUpDown.Maximum);
            }

            //Set Spawn Rate
            if (spawnRateRandomizeCheckBox.Checked)
            {
                if (burstCheckBox.Checked)
                    spawnRateNumericUpDown.Value = random.Next((int)spawnRateNumericUpDown.Minimum, (int)spawnRateNumericUpDown.Maximum);
                else
                    spawnRateNumericUpDown.Value = random.Next((int)spawnRateNumericUpDown.Minimum, 2000);
            }

            //Set Particle Limit
            if (particleLimitRandomizeCheckBox.Checked)
                particleLimitNumericUpDown.Value = random.Next((int)particleLimitNumericUpDown.Minimum, (int)particleLimitNumericUpDown.Maximum);

            //Set Scale 
            if (scaleMinRandomizeCheckBox.Checked)
                scaleStartNumericUpDown.Value = (decimal)((random.Next((int)scaleStartNumericUpDown.Minimum, (int)(scaleStartNumericUpDown.Maximum / scaleStartNumericUpDown.Increment))) * scaleStartNumericUpDown.Increment);
            if (scaleMaxRansomizeCheckBox.Checked)
                scaleEndnumericUpDown.Value = (decimal)(random.Next((int)scaleStartNumericUpDown.Value, (int)(scaleEndnumericUpDown.Maximum / scaleEndnumericUpDown.Increment)) * scaleEndnumericUpDown.Increment);

            //Set Random Color
            rand = random.Next(1, 3);
            if (rand == 1)
                colorRandomCheckBox.Checked = false;
            else if (rand == 2)
                colorRandomCheckBox.Checked = true;

            if (!colorRandomCheckBox.Checked)
            {
                if (colorEndCheckBox.Checked)
                {
                    endColorANumericUpDown.Value = random.Next((int)startColorANumericUpDown.Value, 255);
                    endColorRNumericUpDown.Value = random.Next((int)startColorRNumericUpDown.Value, 255);
                    endColorGNumericUpDown.Value = random.Next((int)startColorGNumericUpDown.Value, 255);
                    endColorBNumericUpDown.Value = random.Next((int)startColorBNumericUpDown.Value, 255);
                }
                if (colorStartRandomizeCheckBox.Checked)
                {
                    startColorANumericUpDown.Value = random.Next(0, 255);
                    startColorRNumericUpDown.Value = random.Next(0, 255);
                    startColorGNumericUpDown.Value = random.Next(0, 255);
                    startColorBNumericUpDown.Value = random.Next(0, 255);
                }
            }

            //Set Velocity
            //Minimum
            if (velocityMinStartRandomizeCheckBox.Checked)
            {
                startVelocityMinXNumericUpDown.Value = random.Next((int)startVelocityMinXNumericUpDown.Minimum,(int)startVelocityMinXNumericUpDown.Maximum);
                startVelocityMinYNumericUpDown.Value = random.Next((int)startVelocityMinYNumericUpDown.Minimum, (int)startVelocityMinYNumericUpDown.Maximum);
            }
            if (velocityMinEndRandomizeCheckBox.Checked)
            {
                endVelocityMinXNumericUpDown.Value = random.Next((int)endVelocityMinXNumericUpDown.Minimum, (int)endVelocityMinXNumericUpDown.Maximum);
                endVelocityMinYNumericUpDown.Value = random.Next((int)endVelocityMinYNumericUpDown.Minimum, (int)endVelocityMinYNumericUpDown.Maximum);
            }

            //Maximum
            if (velocityMaxStartRandomizeCheckBox.Checked)
            {
                startVelocityMaxXNumericUpDown.Value = random.Next((int)startVelocityMinXNumericUpDown.Value, (int)startVelocityMaxXNumericUpDown.Maximum);
                startVelocityMaxYNumericUpDown.Value = random.Next((int)startVelocityMinYNumericUpDown.Value, (int)startVelocityMaxYNumericUpDown.Maximum);

            }
            if (velocityMaxEndRandomizeCheckBox.Checked)
            {
                endVelocityMaxXNumericUpDown.Value = random.Next((int)endVelocityMinXNumericUpDown.Value, (int)endVelocityMaxXNumericUpDown.Maximum);
                endVelocityMaxYNumericUpDown.Value = random.Next((int)endVelocityMinYNumericUpDown.Value, (int)endVelocityMaxYNumericUpDown.Maximum);
            }

            if (accelerationRandomizeCheckBox.Checked)
            {
                //Set Acceleration
                Vector2D acceleration = new Vector2D(random.Next((int)accelXNumericUpDown.Minimum, (int)accelXNumericUpDown.Maximum),
                                                     random.Next((int)accelYNumericUpDown.Minimum, (int)accelYNumericUpDown.Maximum));

                accelXNumericUpDown.Value = (decimal)acceleration.X;
                accelYNumericUpDown.Value = (decimal)acceleration.Y;
            }

            //Set Starting Position Offsets
            if (startingOffsetXRandomizeCheckBox.Checked)
            {
                startingOffsetXLeftnumericUpDown.Value = random.Next((int)startingOffsetXLeftnumericUpDown.Minimum, (int)startingOffsetXLeftnumericUpDown.Maximum);
                startingOffsetXRightnumericUpDown.Value = random.Next((int)startingOffsetXLeftnumericUpDown.Value, (int)startingOffsetXRightnumericUpDown.Maximum);
            }
            if (startingOffsetYCheckBox.Checked)
            {
                startingOffsetYAbovenumericUpDown.Value = random.Next((int)startingOffsetYAbovenumericUpDown.Minimum, (int)startingOffsetYAbovenumericUpDown.Maximum);
                startingOffsetYBelownumericUpDown.Value = random.Next((int)startingOffsetYAbovenumericUpDown.Value, (int)startingOffsetYBelownumericUpDown.Value);
            }


        }

        private void alphaStartTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Alpha_s = alphaStartTrackBar.Value;
            startColorANumericUpDown.Value = alphaStartTrackBar.Value;

        }

        private void redStartTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Red_s = redStartTrackBar.Value;
            startColorRNumericUpDown.Value = redStartTrackBar.Value;
        }

        private void greenStartTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Green_s = greenStartTrackBar.Value;
            startColorGNumericUpDown.Value = greenStartTrackBar.Value;
        }

        private void blueStartTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Blue_s = blueStartTrackBar.Value;
            startColorBNumericUpDown.Value = blueStartTrackBar.Value;
        }

        private void alphaEndTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Alpha_e = alphaEndTrackBar.Value;
            endColorANumericUpDown.Value = alphaEndTrackBar.Value;
        }

        private void redEndTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Red_e = redEndTrackBar.Value;
            endColorRNumericUpDown.Value = redEndTrackBar.Value;
        }

        private void greenEndTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Green_e = greenEndTrackBar.Value;
            endColorGNumericUpDown.Value = greenEndTrackBar.Value;
        }

        private void blueEndTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            emitter.Blue_e = blueEndTrackBar.Value;
            endColorBNumericUpDown.Value = blueEndTrackBar.Value;
        }

        private void particleRenderPanel_MouseUp(object sender, MouseEventArgs e)
        {
            if (emitter == null)
                return;

            drawing = false;
        }

        private void particleRenderPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (emitter == null)
                return;

            if (drawing)
                emitter.Position = position = new Vector2D(e.X, e.Y);
        }

        private void startVelocityMinXNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMaxXNumericUpDown.Value < startVelocityMinXNumericUpDown.Value)
                startVelocityMaxXNumericUpDown.Value = startVelocityMinXNumericUpDown.Value;

            emitter.Initial_velocity_min = new Vector2D((float)startVelocityMinXNumericUpDown.Value, emitter.Initial_velocity_min.Y);
            startVelocityMinXTrackBar.Value = (int)startVelocityMinXNumericUpDown.Value;
        }

        private void startVelocityMinYNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinYNumericUpDown.Value > startVelocityMaxYNumericUpDown.Value)
                startVelocityMaxYNumericUpDown.Value = startVelocityMinYNumericUpDown.Value;

            emitter.Initial_velocity_min = new Vector2D(emitter.Initial_velocity_min.X, (float)startVelocityMinYNumericUpDown.Value);
            startVelocityMinYTrackBar.Value = (int)startVelocityMinYNumericUpDown.Value;
        }

        private void startVelocityMinYTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinYTrackBar.Value > startVelocityMaxYTrackBar.Value)
                startVelocityMaxYTrackBar.Value = startVelocityMinYTrackBar.Value;

            emitter.Initial_velocity_min = new Vector2D(emitter.Initial_velocity_min.X, (float)startVelocityMinYTrackBar.Value);
            startVelocityMinYNumericUpDown.Value = (int)startVelocityMinYTrackBar.Value;
        }

        private void startVelocityMinXTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinXTrackBar.Value > startVelocityMaxXtrackBar.Value)
                startVelocityMaxXtrackBar.Value = startVelocityMinXTrackBar.Value;

            emitter.Initial_velocity_min = new Vector2D((float)startVelocityMinXTrackBar.Value, emitter.Initial_velocity_min.Y);
            startVelocityMinXNumericUpDown.Value = startVelocityMinXTrackBar.Value;
        }

        private void startVelocityMaxXNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMaxXNumericUpDown.Value < startVelocityMinXNumericUpDown.Value)
                startVelocityMaxXNumericUpDown.Value = startVelocityMinXNumericUpDown.Value;

            emitter.Initial_velocity_max = new Vector2D((float)startVelocityMaxXNumericUpDown.Value, emitter.Initial_velocity_max.Y);
            startVelocityMaxXtrackBar.Value = (int)startVelocityMaxXNumericUpDown.Value;
        }

        private void startVelocityMaxXtrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinXTrackBar.Value > startVelocityMaxXtrackBar.Value)
                startVelocityMaxXtrackBar.Value = startVelocityMinXTrackBar.Value;

            emitter.Initial_velocity_max = new Vector2D(emitter.Initial_velocity_max.X, (float)startVelocityMaxXtrackBar.Value);
            startVelocityMaxXNumericUpDown.Value = (decimal)startVelocityMaxXtrackBar.Value;
        }

        private void endVelocityMinXNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMaxXNumericUpDown.Value < startVelocityMinXNumericUpDown.Value)
                startVelocityMaxXNumericUpDown.Value = startVelocityMinXNumericUpDown.Value;

            emitter.Final_velocity_min = new Vector2D((float)endVelocityMinXNumericUpDown.Value, emitter.Final_velocity_min.Y);
            endVelocityMinXTrackBar.Value = (int)endVelocityMinXNumericUpDown.Value;
        }

        private void endVelocityMinXTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxXTrackBar.Value < endVelocityMinXTrackBar.Value)
                endVelocityMaxXTrackBar.Value = endVelocityMinXTrackBar.Value;

            emitter.Final_velocity_min = new Vector2D((float)endVelocityMinXTrackBar.Value, emitter.Final_velocity_min.Y);
            endVelocityMinXNumericUpDown.Value = endVelocityMinXTrackBar.Value;
        }

        private void endVelocityMinYNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxYNumericUpDown.Value < endVelocityMinYNumericUpDown.Value)
                endVelocityMaxYNumericUpDown.Value = endVelocityMinYNumericUpDown.Value;

            emitter.Final_velocity_min = new Vector2D(emitter.Final_velocity_min.X, (float)endVelocityMinYNumericUpDown.Value);
            endVelocityMinYTrackBar.Value = (int)endVelocityMinYNumericUpDown.Value;
        }

        private void endVelocityMinYTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxYTrackBar.Value < endVelocityMinYTrackBar.Value)
                endVelocityMaxYTrackBar.Value = endVelocityMinYTrackBar.Value;

            emitter.Final_velocity_min = new Vector2D(emitter.Final_velocity_min.X, (float)endVelocityMinYTrackBar.Value);
            endVelocityMinYNumericUpDown.Value = endVelocityMinYTrackBar.Value;
        }

        private void endVelocityMaxXNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxXNumericUpDown.Value < endVelocityMinXNumericUpDown.Value)
                endVelocityMaxXNumericUpDown.Value = endVelocityMinXNumericUpDown.Value;

            emitter.Final_velocity_max = new Vector2D((float)endVelocityMaxXNumericUpDown.Value, emitter.Final_velocity_max.Y);
            endVelocityMaxXTrackBar.Value = (int)endVelocityMaxXNumericUpDown.Value;
        }

        private void endVelocityMaxXTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxXTrackBar.Value < endVelocityMinXTrackBar.Value)
                endVelocityMaxXTrackBar.Value = endVelocityMinXTrackBar.Value;

            emitter.Final_velocity_max = new Vector2D((float)endVelocityMaxXTrackBar.Value, emitter.Final_velocity_max.Y);
            endVelocityMaxXNumericUpDown.Value = endVelocityMaxXTrackBar.Value;

        }

        private void endVelocityMaxYTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxYTrackBar.Value < endVelocityMinYTrackBar.Value)
                endVelocityMaxYTrackBar.Value = endVelocityMinYTrackBar.Value;

            emitter.Final_velocity_max = new Vector2D(emitter.Final_velocity_max.X, (float)endVelocityMaxYTrackBar.Value);
            endVelocityMaxYNumericUpDown.Value = endVelocityMaxYTrackBar.Value;

        }

        private void endVelocityMaxYNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (endVelocityMaxYNumericUpDown.Value < endVelocityMinYNumericUpDown.Value)
                endVelocityMaxYNumericUpDown.Value = endVelocityMinYNumericUpDown.Value;

            emitter.Final_velocity_max = new Vector2D(emitter.Final_velocity_max.X, (float)endVelocityMaxYNumericUpDown.Value);
            endVelocityMaxYTrackBar.Value = (int)endVelocityMaxYNumericUpDown.Value;

        }

        private void startVelocityMaxYTrackBar_Scroll(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinYTrackBar.Value > startVelocityMaxYTrackBar.Value)
                startVelocityMaxYTrackBar.Value = startVelocityMinYTrackBar.Value;

            emitter.Initial_velocity_max.Y = (float)startVelocityMaxYTrackBar.Value;
            startVelocityMaxYNumericUpDown.Value = startVelocityMaxYTrackBar.Value;

        }

        private void startVelocityMaxYNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (emitter == null)
                return;

            if (startVelocityMinYNumericUpDown.Value > startVelocityMaxYNumericUpDown.Value)
                startVelocityMaxYNumericUpDown.Value = startVelocityMinYNumericUpDown.Value;

            emitter.Initial_velocity_max = new Vector2D(emitter.Initial_velocity_max.X, (float)startVelocityMaxYNumericUpDown.Value);
            startVelocityMaxYTrackBar.Value = (int)startVelocityMaxYNumericUpDown.Value;
        }
    }
}
